package com.tanhua.manager.service;

import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tanhua.manager.constant.CacheKey;
import com.tanhua.manager.domain.Admin;
import com.tanhua.manager.exception.BusinessException;
import com.tanhua.manager.interceptor.AdminHolder;
import com.tanhua.manager.mapper.AdminMapper;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

/**
 * @author anshuai
 * @create 2021-02-20 15:23
 */
@Service
public class AdminService {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private AdminMapper adminMapper;

    @Value("${tanhua.secret}")
    private String secret;

    /**
     * 将生成图片验证码缓存到redis
     *
     * @param code 验证码的值
     * @param uuid 客户端传过来的唯一标识
     */
    public void cacheCode(String code, String uuid) {
        //设置缓存时间为3分钟
        redisTemplate.opsForValue().set(CacheKey.CODE_PREFIX + uuid, code, Duration.ofMinutes(3));
    }

    /**
     * 用户登录
     *
     * @param username         账号
     * @param password         密码
     * @param verificationCode 验证码
     * @param uuid             获取验证码时uuid,redis的key
     */
    public ResponseEntity login(String username, String password, String verificationCode, String uuid) {

        //1.先校验验证码
        String value = redisTemplate.opsForValue().get(CacheKey.CODE_PREFIX + uuid);
        if (value == null || !value.equals(verificationCode)) {
            throw new BusinessException("验证码错误!");
        }
        //登录成功删除缓存的验证码
        redisTemplate.delete(CacheKey.CODE_PREFIX + uuid);

        //2.校验用户名和密码
        QueryWrapper<Admin> wrapper = new QueryWrapper<>();
        wrapper.eq("username", username);
        wrapper.eq("password", SecureUtil.md5(password));

        Admin admin = adminMapper.selectOne(wrapper);
        if (admin == null) {
            throw new BusinessException("帐号或密码错误!");
        }

        //3.生成token
        Map<String, Object> claims = new HashMap<>();
        claims.put("id", admin.getId());
        claims.put("username", admin.getUsername());

        String token = Jwts.builder()
                .setClaims(claims)
                .signWith(SignatureAlgorithm.HS256, secret)
                .compact();

        //4. 把管理员Admin缓存起来
        redisTemplate.opsForValue().set(CacheKey.TOKEN_PREFIX + token, JSON.toJSONString(admin), Duration.ofHours(1));

        //5.返回结果
        Map<String, Object> result = new HashMap<>();
        result.put("token", token);
        return ResponseEntity.ok(result);
    }

    /**
     * 登录-登录后加载用户信息
     *
     * @return 用户信息
     */
    public ResponseEntity getAdminInfo() {

        //1. 从Redis中获取token对应的用户信息
        Admin admin = AdminHolder.getAdmin();
        //2. 响应给客户端（注意，不要把密码响应给客户端）
        Map<String, Object> result = new HashedMap();
        result.put("id", admin.getId());
        result.put("username", admin.getUsername());
        result.put("avatar", admin.getAvatar());

        return ResponseEntity.ok(result);
    }

    /**
     * 退出登录
     *
     * @return
     */
    public ResponseEntity logout() {
        //删除redis中的token数据
        redisTemplate.delete(CacheKey.TOKEN_PREFIX + AdminHolder.getToken());
        return ResponseEntity.ok(null);
    }
}
